﻿module Azimuth

open System
open Time
open Coordinates

let DegreeToRadian(angle:double) = 
   Math.PI * angle / 180.0

let RadianToDegree(angle: double) = 
   angle * (180.0 / Math.PI)

let CalculateAzimuth (rightAscension:RightAscension, declination:Declination, lst:System.DateTime, latitude:Latitude) =
    let H = Time.HourAngleFromLocalSiderealTime(Convert.ToDouble(lst.Hour), Convert.ToDouble(lst.Minute), Convert.ToDouble(lst.Second), Convert.ToDouble(rightAscension.Hour), Convert.ToDouble(rightAscension.Minute), Convert.ToDouble(rightAscension.Second))
    let H2 = H * 15.00

    let delta = Time.DegreesMinutesSecondsToDecimalDegrees(Convert.ToDouble(declination.Degree) ,Convert.ToDouble(declination.Minute) ,Convert.ToDouble(declination.Second))

    let lat = Time.DegreesMinutesSecondsToDecimalDegrees(Convert.ToDouble(latitude.Degree), Convert.ToDouble(latitude.Minute), Convert.ToDouble(latitude.Second))

    let sinALT = Math.Sin(DegreeToRadian(delta)) * Math.Sin(DegreeToRadian(lat)) + Math.Cos(DegreeToRadian(delta)) * Math.Cos(DegreeToRadian(lat)) * Math.Cos(DegreeToRadian(H2))
    let ALT = RadianToDegree(Math.Asin(sinALT))

    let top = Math.Sin(DegreeToRadian(delta)) - Math.Sin(DegreeToRadian(ALT)) * Math.Sin(DegreeToRadian(lat))
    let bottom = Math.Cos(DegreeToRadian(ALT)) * Math.Cos(DegreeToRadian(lat))
    let cosA = top / bottom

    let a = RadianToDegree(Math.Acos(cosA))

    let sinH2 = Math.Sin(DegreeToRadian(H2))

    let AZ = if sinH2 > 0.00 then 360.00F - Convert.ToSingle(a) else Convert.ToSingle(a)


    AZ